﻿package smlab.utils
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Loader;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.ContextMenuEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.StatusEvent;
	import flash.filters.BitmapFilter;
	import flash.system.LoaderContext;
	import flash.system.SecurityDomain;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.ui.ContextMenu;
	import flash.ui.ContextMenuItem;
	import flash.ui.Keyboard;

	public class Trace_SM extends Sprite
	{	
		private var textLayer:Sprite;
		private var dragLayer:Sprite;
		private var stateLayer:Sprite;
		private var debugger_TF : TextField;
		private var id:int=-1;
		private var testLoader:Loader;
		private var format:TextFormat;
		private var debugbg1:Shape;
		private var debugbg2:Shape;
		private var drag:Shape;
		private var _isInit:Boolean=false;
		private var container:DisplayObjectContainer;
		private static var ins:Trace_SM;
		
		public function Trace_SM()
		{
			if(ins){
				throw new Error("Trace_SM 是单例，请勿重复实例化");
			}
		}
		
		public function get isInit():Boolean
		{
			return _isInit;
		}
		
		/**
		 * 请勿调用此方法
		 * 
		 */
		public function set isInit(b:Boolean):void
		{
			trace("请勿调用此方法 Trace_SM.isInit()");
		}
		
		/**
		 * 初始化
		 * @param container$	最好是 stage 或者确保是最顶层的容器，不然你看不见我的
		 * @return 
		 * 
		 */
		public function init(container$:DisplayObjectContainer): void
		{
			if(!container$){
				throw new Error("Trace_SM 调试器的顶层容器不能为空");
			}
			
			if(container){
				container.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
				container=null;
			}
			
			container=container$;
			
			if(_isInit==false){
				textLayer = new Sprite();
				dragLayer = new Sprite();
				stateLayer = new Sprite();
				debugger_TF  = new TextField();
				debugger_TF.background = true; 
				debugger_TF.backgroundColor = 0xFFFFcc;
				debugger_TF.border = true;
				debugger_TF.selectable = true;
				debugger_TF.multiline = true;
				debugger_TF.mouseWheelEnabled = true;
				debugger_TF.height = 500;
				debugger_TF.width = 400;
				debugger_TF.wordWrap=true;
				debugger_TF.scrollV =debugger_TF.maxScrollV;
				
				format = new TextFormat();
				format.font = "Verdana";
				format.color = 0x000000;
				format.size = 12;
				
				debugger_TF.defaultTextFormat = format;	
				debugger_TF.x = 0;
				debugger_TF.y = 0;
				
				/**
				 * 绘制按钮和拖动框的图形
				 * */
				debugbg1 = createBar(0xFFFFFF,  3,  400, 300, 50, -460);
				debugbg2 = doDrawRect(0x333333, 2, 0x0000cc, 400, 300, 52, -451);
				debugbg1.x = 10;
				debugbg1.y = 10;
				drag = createBar(0x000000, .3, 400, 20, 50, -450);
				dragLayer.addChild(drag);
				
				textLayer.addChild(dragLayer);
				textLayer.addChild(debugger_TF);
				
				/**
				 * 拖动框的拖动事件
				 * */
				dragLayer.addEventListener(MouseEvent.MOUSE_DOWN, _onStarDrag);
				dragLayer.addEventListener(MouseEvent.MOUSE_UP, _onStopDrag);
				
				var menu:ContextMenu = new ContextMenu();
				menu.hideBuiltInItems();
				var item:ContextMenuItem = new ContextMenuItem("清除");
				menu.customItems.push(item);
				item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, clearHandler);
				debugger_TF.contextMenu = menu;
				
				_isInit=true;
			}
			
			textLayer.visible=false;
			container.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
			Trace_SM.trace("");
		}
		
		public static function getInstance():Trace_SM
		{
			if(!ins){
				ins=new Trace_SM();
			}
			return ins;
		}
		
		/**
		 * 呼出和关闭（关闭后不再接收 trace 信息）：“ctrl+shift+~”键
		 * 显示和隐藏（继续收取 trace 信息）：“Q”键
		 * @param evt
		 * 
		 */
		private function keyDownHandler(evt:KeyboardEvent):void
		{
			if(evt.ctrlKey && evt.shiftKey && evt.keyCode==81 && textLayer.parent!=null)//隐藏/显示
			{
				textLayer.visible=!textLayer.visible
				if(textLayer.visible){
					container.addChild(textLayer);
				}
			}
			
			if (evt.ctrlKey && evt.shiftKey && evt.keyCode==192)//启动，关闭
			{
				if(textLayer.parent==null){
					textLayer.visible=true;
					container.addChild(textLayer);
					debugger_TF.text="";
					Trace_SM.trace("超兽武装-调试信息","快捷键：","【CTRL+SHIFT+~ 】启动/关闭（清除）调试器","【CTRL+SHIFT+Q】隐藏/显示调试器");
				}else{
					debugger_TF.text="";
					container.removeChild(textLayer);
				}
			}
		}
		private function _onStarDrag(evt:MouseEvent):void
		{
			textLayer.startDrag();
		}
		private function _onStopDrag(evt:MouseEvent):void
		{
			textLayer.stopDrag();
		}
		private static function showText():void
		{
			Trace_SM.getInstance().debugger_TF.parent.visible = true;	
		}
		private function clearHandler(ev:ContextMenuEvent):void
		{
			Trace_SM.clear();
		}
		
		public  static function trace(...str) : void 
		{
			if(Trace_SM.getInstance()._isInit==false){
				throw new Error("请先初始化调试器，比如： Trace_SM.getInstance().init(stage);");
			};
			
			if(Trace_SM.getInstance().textLayer.parent==null){
				return;
			}else{
				var s:String = "";
				
				for (var i:int = 0; i < str.length; i++ )
				{
					s += str[i] + " \n";
				}
				
				Trace_SM.getInstance().debugger_TF.appendText(s);			
				Trace_SM.getInstance().debugger_TF.appendText("\n"+"######################################"+"\n");
				Trace_SM.getInstance().debugger_TF.scrollV = Trace_SM.getInstance().debugger_TF.maxScrollV;
			}
		}
		
		public static function clear():void
		{
			if(Trace_SM.getInstance().debugger_TF){
				Trace_SM.getInstance().debugger_TF.text = "";
			}
		}
		private function createBar(color:uint, alpha:Number, width:int,height:int,x:int, y:int):Shape 
		{
			var s:Shape = new Shape();
			s.graphics.beginFill(color, alpha);
			s.graphics.drawRoundRect(0,0,width,height,20);
			s.graphics.endFill();
			s.x = x;
			s.y = y;
			return s;
		}
		private function doDrawRect(linecolor:uint,linesize:int,bgcolor:uint,width:int,height:int,x:int,y:int):Shape {
            var s:Shape = new Shape();
            s.graphics.beginFill(bgcolor);
            s.graphics.lineStyle(linesize, linecolor);
            s.graphics.drawRoundRect(0, 0, width, height,20);
            s.graphics.endFill();
            s.x = x;
			s.y = y;
			return s;
        }
	}
}